#include "clientmanager.h"
#include <QDebug>

ClientManager::ClientManager(QObject *parent)
    : QObject(parent) {
}

ClientManager::~ClientManager() {
    QMutexLocker locker(&m_mutex);
    for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
        it.value()->stop();
        it.value()->deleteLater();
    }
    m_clients.clear();
}

void ClientManager::addClient(qintptr descriptor) {
    QMutexLocker locker(&m_mutex);
    
    if (m_clients.contains(descriptor)) {
        QTextStream(stdout) << "Client already exists:" << descriptor<<"\n";
        return;
    }

    ClientConnection *client = new ClientConnection(descriptor, this);
    
    connect(client, &ClientConnection::clientDisconnected,
            this, &ClientManager::onClientDisconnected);
    connect(client, &ClientConnection::messageReceived,
            this, &ClientManager::onMessageReceived);
    connect(client, &ClientConnection::errorOccurred,
            this, &ClientManager::onErrorOccurred);

    m_clients.insert(descriptor, client);
    client->start();

    emit clientConnected(descriptor, client->clientInfo());
    QTextStream(stdout) << "Added client:" << descriptor << "Total clients:" << m_clients.size()<<"\n";
}

void ClientManager::removeClient(qintptr descriptor) {
    QMutexLocker locker(&m_mutex);
    
    if (m_clients.contains(descriptor)) {
        ClientConnection *client = m_clients.take(descriptor);
        client->stop();
        client->deleteLater();
        
        emit clientDisconnected(descriptor);
        qDebug() << "Removed client:" << descriptor << "Remaining clients:" << m_clients.size()<<"\n";
    }
}

void ClientManager::broadcastMessage(const QString &message) {
    QMutexLocker locker(&m_mutex);
    
    for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
        it.value()->sendMessage(message);
    }
}

void ClientManager::sendToClient(qintptr descriptor, const QString &message) {
    QMutexLocker locker(&m_mutex);
    
    if (m_clients.contains(descriptor)) {
        m_clients[descriptor]->sendMessage(message);
    }
}

int ClientManager::clientCount() const {
    QMutexLocker locker(&m_mutex);
    return m_clients.size();
}

QList<qintptr> ClientManager::clientList() const {
    QMutexLocker locker(&m_mutex);
    return m_clients.keys();
}

void ClientManager::onClientDisconnected(qintptr descriptor) {
    removeClient(descriptor);
}

void ClientManager::onMessageReceived(qintptr descriptor, const QString &message) {
    emit messageReceived(descriptor, message);
}

void ClientManager::onErrorOccurred(qintptr descriptor, const QString &error) {
    QTextStream(stdout) << "Client error:" << descriptor << error<<"\n";
    emit errorOccurred(descriptor, error);
}
